Skip to main content

Babel

Why Babel Is Needed

Imagine you're targeting both modern browsers and Internet Explorer (which doesn't support ES6 or modern features)

Without Babel

<script>
const greet = (name) => `Hello, ${name}`;
console.log(greet("Alice"));
</script>
  • Modern browsers: It will run just fine.
  • IE 11: Throws an error because it doesn’t recognize arrow functions.

With Babel (After Transpilation)

<script>
var greet = function greet(name) {
return "Hello, " + name;
};
console.log(greet("Alice"));
</script>
  • Modern browsers: It still works perfectly (Babel just ensures compatibility).
  • IE 11: It runs without errors because Babel has converted the arrow function into a regular function.

What Is Babel

Babel is a JavaScript compiler (transpiler) that allows developers to write modern JavaScript (ES6+ or newer) and convert it into older versions (like ES5) so that it can run in environments (like older browsers or Node.js versions) that don’t yet support the latest features.

Think of Babel as a translator that takes your "new language" (modern JavaScript) and converts it into an "old language" (JavaScript that all browsers understand).

Installation

  1. Install Babel

    npm init -y
    npm install --save-dev @babel/core @babel/cli @babel/preset-env
  2. Create Babel config file (babel.config.json)

    {
    "presets": ["@babel/preset-env"]
    }
  3. Run Babel

    npx babel js/src --out-dir js/dist

This compiles all files from src/ to dist/.

Babel Presets & Plugins

  • Presets = groups of plugins.
    • @babel/preset-env – Transpile ES6+
    • @babel/preset-react – For JSX (React)
    • @babel/preset-typescript – For TypeScript
  • Plugins = individual transformations.
    • @babel/plugin-proposal-optional-chaining
    • @babel/plugin-transform-arrow-functions

How Babel Works

When you run Babel on a file, it goes through three main phases:

  1. Parsing (Code → AST)
  2. Transforming (AST → Modified AST)
  3. Code Generation (Modified AST → Code)

This pipeline is very similar to how compilers work, but Babel is a transpiler (source-to-source compiler).

1. Parsing (Code → AST)

Parsing happens in two sub-steps:

1. Lexical Analysis (Tokenization)

The input JavaScript code is split into tokens (smallest units like const, =, (, ), {, }).

const firstName = "Masum";
const lastName = "Billah";

Tokens might look like:

[
{ type: "Keyword", value: "const" },
{ type: "Identifier", value: "firstName" },
{ type: "Punctuator", value: "=" },
{ type: "String", value: "Masum" },
{ type: "Punctuator", value: ";" },
{ type: "Keyword", value: "const" },
{ type: "Identifier", value: "lastName" },
{ type: "Punctuator", value: "=" },
{ type: "String", value: "Billah" },
{ type: "Punctuator", value: ";" },
];

2. Syntactic Analysis

Next, Babel transforms these tokens into an Abstract Syntax Tree (AST). The AST is a tree structure that represents the syntax of the code.

For the two variable declarations:

{
"type": "VariableDeclaration",
"kind": "const",
"declarations": [
{
"type": "VariableDeclarator",
"id": { "type": "Identifier", "name": "firstName" },
"init": { "type": "Literal", "value": "Masum" }
},
{
"type": "VariableDeclarator",
"id": { "type": "Identifier", "name": "lastName" },
"init": { "type": "Literal", "value": "Billah" }
}
]
}

Babel uses @babel/parser to do this job.

2. Transforming (AST → Modified AST)

Now, Babel applies transformations based on the plugins and presets you have in your configuration. However, since there’s no modern syntax to transform in this simple example, we’re essentially working with no-op transformations.

Example Transformation

If there were transformations (like changing const to var, or converting arrow functions), Babel would modify the AST. For this case, no such transformation is needed, so the AST remains the same.

For example, if you had a transformation to convert const to var, Babel would modify the AST as follows:

Original AST (simplified):


{
"type": "VariableDeclaration",
"kind": "const", // To be transformed to 'var'
"declarations": [ ... ]
}

Transformed AST:

{
"type": "VariableDeclaration",
"kind": "var", // After transformation from 'const' to 'var'
"declarations": [ ... ]
}

Used Tool

  • This is where @babel/traverse and plugins work:
  • @babel/plugin-transform-arrow-functions sees ArrowFunctionExpression nodes.
  • Rewrites them as FunctionExpression nodes.

3. Code Generation (Modified AST → Code)

Finally, after Babel processes the AST and applies the necessary transformations, it generates the final JavaScript code.

If there were no transformations, the output would look like this:

const firstName = "Masum";
const lastName = "Billah";

If Babel had transformed the const declarations into var, the generated code would look like this:

"use strict";

var firstName = "Masum";
var lastName = "Billah";
  • "use strict" is added automatically by Babel for better error handling.
  • const is converted to var, which is supported by older browsers like Internet Explorer 11.

Used Tool

  • @babel/traverse → Walks through AST nodes
  • @babel/types → Helpers for building/modifying AST nodes
  • @babel/generator → Turns AST back into code
  • @babel/core → Orchestrates everything